package com.icen.utils.comm;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * String Utils Class
 * 
 * @author IcenHan
 *
 */
public class StringUtils {

	/**
	 * null转""
	 * 
	 * @param str
	 *            代转字符串
	 * @return String
	 */
	public static String nullToEmpty(String str) {
		return (str == null ? "" : str);
	}

	/**
	 * 字符串首字母大写
	 * 
	 * @param str
	 *            需要转换的字符串
	 * @return String
	 * 
	 */
	public static String capitalizeFirstLetter(String str) {
		if (ValidateUtils.isEmpty(str)) {
			return str;
		}

		char c = str.charAt(0);
		return (!Character.isLetter(c) || Character.isUpperCase(c)) ? str
				: new StringBuilder(str.length())
						.append(Character.toUpperCase(c))
						.append(str.substring(1)).toString();
	}

	/**
	 * 全角符字符串转换为半角符字符串
	 * 
	 * @param str
	 *            需要转换的字符串
	 * @return String
	 *         <p>
	 *         出现异常,返回原数据
	 *         </p>
	 */
	public static String fullWidthToHalfWidth(String str) {
		if (ValidateUtils.isEmpty(str)) {
			return str;
		}

		char[] source = str.toCharArray();
		for (int i = 0; i < source.length; i++) {
			if (source[i] == 12288) {
				source[i] = ' ';
			} else if (source[i] >= 65281 && source[i] <= 65374) {
				source[i] = (char) (source[i] - 65248);
			} else {
				source[i] = source[i];
			}
		}
		return new String(source);
	}

	/**
	 * 半角符字符串转换为全角符字符串
	 * 
	 * @param str
	 *            需要转换的字符串
	 * @return String
	 *         <p>
	 *         出现异常,返回原数据
	 *         </p>
	 */
	public static String halfWidthToFullWidth(String str) {
		if (ValidateUtils.isEmpty(str)) {
			return str;
		}

		char[] source = str.toCharArray();
		for (int i = 0; i < source.length; i++) {
			if (source[i] == ' ') {
				source[i] = (char) 12288;
			} else if (source[i] >= 33 && source[i] <= 126) {
				source[i] = (char) (source[i] + 65248);
			} else {
				source[i] = source[i];
			}
		}
		return new String(source);
	}

	/**
	 * 返回字符串dest在字符串source中出现的次数.要查找的字符串是区分大小写的.
	 * 
	 * @param source
	 *            原字符串.
	 * @param dest
	 *            要搜索的字符串.
	 * @return int
	 */
	public static int containSum(String source, String dest) {
		return (source.length() - StringUtils.replacStr(source, dest, "")
				.length()) / dest.length();
	}

	/**
	 * 将字符串中的str01替换成str02
	 * 
	 * @param str01
	 *            要替换的普通字符串.
	 * @param str02
	 *            要替换成的字符串
	 * @return String
	 */
	public static String replacStr(String resStr, String str01, String str02) {
		StringBuilder sb = new StringBuilder();
		int b, e = 0, len = str01.length();
		while ((b = resStr.indexOf(str01, e)) != -1) {
			sb.append(resStr.substring(e, b));
			sb.append(str02);
			e = b + len;
		}
		if (e < resStr.length()) {
			sb.append(resStr.substring(e));
		}
		return sb.toString();
	}

	/**
	 * 将字符串中符合regStr正则模式的字符串替换为s. 此操作将替换所有符合正则匹配条件的字符串.
	 * 
	 * @param str
	 * @param regStr
	 *            用于匹配的正则表达式
	 * @param s
	 *            要替换符合匹配内容的字符串
	 * @return String
	 */
	public static String replaceRegStrAll(String str, String regStr, String s) {
		Pattern pattern = Pattern.compile(regStr);
		Matcher matcher = pattern.matcher(str);
		return matcher.replaceAll(s);
	}

	/**
	 * 将字符串中符合正则匹配的字符串替换为s. 此操作将仅替换一次符合正则匹配条件的字符串.
	 * 
	 * @param str
	 * @param regStr
	 *            用于匹配的正则表达式
	 * @param s
	 *            要替换符合匹配内容的字符串
	 * @return String
	 */
	public static String replaceRegStrFirst(String str, String regStr, String s) {
		Pattern pattern = Pattern.compile(regStr);
		Matcher matcher = pattern.matcher(str);
		return matcher.replaceFirst(s);
	}

	/**
	 * 截字符串前面的指定数量个字符
	 * <p>
	 * 如果字节符度超过截取的数量,则后面用省略号代替(因为省略号会占去两个字符，因此当有省略号时,实际显示的字符数=toCount-2)
	 * </p>
	 * 
	 * @param str
	 *            要截取的字符串
	 * @param toCount
	 *            要截取的字符数（一个汉字计两个字符）
	 * @return String
	 */
	public static String subStr(String str, int toCount) {
		try {
			StringBuilder reStr = new StringBuilder("");
			char[] tempChar = str.toCharArray();
			for (int i = 0; i < tempChar.length; i++) {
				byte[] b = String.valueOf(tempChar[i]).getBytes("utf-8");
				toCount -= b.length > 1 ? 2 : 1;
				if (toCount <= 0) {
					if (i == tempChar.length - 1) {
						reStr.append(tempChar[i]);
					} else {
						reStr.append("…");
						break;
					}
				} else {
					reStr.append(tempChar[i]);
				}
			}
			return reStr.toString();
		} catch (java.io.UnsupportedEncodingException ex) {
			return str;
		}
	}

	/**
	 * 将字符串按指定的分隔符分割成为一个数组. <br />
	 * 
	 * @param str
	 *            要转换的字符串.
	 * @param sp
	 *            分隔字符串.
	 */
	public static String[] strToStrArr(String str, String sp) {
		List<String> arrayList = new ArrayList<String>();
		int index = 0, offset = 0, len = sp.length();
		while ((index = str.indexOf(sp, index + len)) != -1) {
			arrayList.add(str.substring(offset, index));
			offset = index + len;
		}
		if (offset < str.length())
			arrayList.add(str.substring(offset));
		return arrayList.toArray(new String[arrayList.size()]);
	}

	/**
	 * 测试字符串是否能够匹配该正则模式(完全匹配).
	 * 
	 * @param str
	 * @param regStr
	 *            正则. 由于此方法为完全匹配，因此regStr正则模式往往以^开头，以$结尾.
	 * @return boolean
	 */
	public static boolean regTest(String str, String regStr) {
		Pattern pattern = Pattern.compile(regStr);
		Matcher matcher = pattern.matcher(str);
		return matcher.matches();
	}

	/**
	 * 测试字符串是否包含该正则模式.
	 * 
	 * @param str
	 * @param regStr
	 *            正则
	 * @return boolean
	 */
	public static boolean regFind(String str, String regStr) {
		Pattern pattern = Pattern.compile(regStr);
		Matcher matcher = pattern.matcher(str);
		return matcher.find();
	}

	/**
	 * 此方法将HTML内容转换为普通文本. <br/>
	 * 此方法将通过对正则替换，删除inputString中的HTML标签，并返回纯文本内容．
	 * 
	 * @param inputString
	 *            要转换的HTML代码.
	 * @return String
	 */
	public static String htmlToText(String inputString) {
		String htmlStr = inputString;
		String textStr = "";
		String scriptRegEx = "<[\\s]*?script[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?script[\\s]*?>";
		String styleRegEx = "<[\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>";
		String htmlRegEx1 = "<[^>]*>";
		String htmlRegEx2 = "<[^>]*";
		try {
			Pattern scriptPattern = Pattern.compile(scriptRegEx,
					Pattern.CASE_INSENSITIVE);
			Matcher scriptMatcher = scriptPattern.matcher(htmlStr);
			htmlStr = scriptMatcher.replaceAll("");
			Pattern stylePattern = Pattern.compile(styleRegEx,
					Pattern.CASE_INSENSITIVE);
			Matcher styleMatcher = stylePattern.matcher(htmlStr);
			htmlStr = styleMatcher.replaceAll("");
			Pattern htmlPattern1 = Pattern.compile(htmlRegEx1,
					Pattern.CASE_INSENSITIVE);
			Matcher htmlMatcher1 = htmlPattern1.matcher(htmlStr);
			htmlStr = htmlMatcher1.replaceAll("");
			Pattern htmlPattern2 = Pattern.compile(htmlRegEx2,
					Pattern.CASE_INSENSITIVE);
			Matcher htmlMatcher2 = htmlPattern2.matcher(htmlStr);
			htmlStr = htmlMatcher2.replaceAll("");
			textStr = htmlStr;
		} catch (Exception e) {
			System.err.println("->Txt.htmlToText(String inputString) ERROR:"
					+ e.getMessage());
		}
		textStr = textStr.replaceAll("&acute;", "\'");
		textStr = textStr.replaceAll("&quot;", "\"");
		textStr = textStr.replaceAll("&lt;", "<");
		textStr = textStr.replaceAll("&gt;", ">");
		textStr = textStr.replaceAll("&nbsp;", " ");
		textStr = textStr.replaceAll("&amp;", "&");
		return textStr;
	}

	/**
	 * 将指定的字符串内容进行HTML标签转换过滤
	 * <p>
	 * 此方法会将内容中的HTML标签转换成普通字符输出以防止非法的HTML代码被执行; 同时此方法自动识别URL地址、邮件地址并为其添加链接.
	 * </p>
	 * <strong>注意：</strong> 由在线WEB编辑器添加的内容，不应调用此方法，否则编辑器上传的所有HTML代码将被转换成普通字符输出。
	 * 
	 * @param str
	 *            要进行HTML标签过滤处理处理的原字符串
	 * @return 转换之后的字符串
	 */
	public static String htmlToHtmlText(String str) {
		String s = str.replaceAll("<", "&lt;").replaceAll(">", "&gt;")
				.replaceAll("\"", "&quot;").replaceAll("'", "&acute; ")
				.replaceAll("  ", " &nbsp;").replaceAll("\\r\\n", "<br/>")
				.replaceAll("\\n", "<br/>");
		String st = StringUtils.replaceRegStrAll(s,
				"http://([%#=&\\?\\./a-zA-Z0-9]+)",
				"<a href=\"http://$1\" target=\"_blank\">http://$1</a>");
		String result = StringUtils.replaceRegStrAll(st,
				"([-_a-z0-9]+?)@([-_\\.a-zA-Z0-9]{5,})",
				"<a href=\"mailto:$1@$2\" target=\"_blank\">$1@$2</a>");
		return result;
	}
}
